/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
*/

#include "version.h"
#include "insim.h"
#include "miscfuncs.h"

#include "hooks_keepalive.h"
#include "hooks_lua.h"
//#include "hooks_translate.h"

struct insim_t *I = NULL;

void hooks_print(void *d)
{
    struct hooks_t *t = d;
    if ((t != NULL) && (t->name != NULL))
        printf("Registered '%s' module\n", t->name);
    return;
}

int main (int argc, char *argv[])
{

 // repeat
 /*
 FILE *fp;
  if((fp=freopen("error.log", "a+" ,stderr))==NULL) {
    printf("Can't open file.\n");
    exit(1);
  }
*/
//


    fprintf(stderr,"LuaLFS v%s\nPowered By %s\n\n%s\n\n", VERSION, LUA_VERSION, WARRANTY);

    /* Create hooks we'll need */

    /* Keepalive hook
        - responds to the keepalive packets from LFS - MUST BE PRESENT TO PREVENT TIMEOUTS
        - monitors the connection and time(s) between connecting and also receiving IS_VER
        - monitors when LFS last contacted us, incase TCP fails
    */
    struct hooks_t hook_keepalive;
    memset(&hook_keepalive, 0, sizeof(struct hooks_t));
    strcpy(hook_keepalive.name, "Keepalive");
    hook_keepalive.fp_create = hkeepalive_create;
    hook_keepalive.fp_connected = hkeepalive_connected;
    hook_keepalive.fp_prerecv = hkeepalive_prerecv;
    hook_keepalive.fp_recv = hkeepalive_recv;
    hook_keepalive.fp_close = hkeepalive_close;
    //my include (repeat)
    hook_keepalive.fp_thread = hkeepalive_thread;

    // Translate hook
    /*
    struct hooks_t hook_translate;
    memset(&hook_translate, 0, sizeof(struct hooks_t));
    strcpy(hook_translate.name, "Translate");
    hook_translate.fp_recv = translate_recv;
    */

    // Lua Hook - loads the actual lua engine and config into insim_t variable - OPTIONAL, but insim_t
    // struct must be correctly populated if unused
    struct hooks_t hook_lua;
    memset(&hook_lua, 0, sizeof(struct hooks_t));
    strcpy(hook_lua.name, "Lua");
    hook_lua.fp_create = hlua_create;
    hook_lua.fp_connected = hlua_connected;
    hook_lua.fp_disconnected = hlua_disconnected;
    hook_lua.fp_recv = hlua_recv;
    hook_lua.fp_close = hlua_close;
    //my include (repeat)
    hook_lua.fp_thread = hlua_thread;

    I = insim_create();

    if (I == NULL)
    {
        fprintf(stderr, "insim_create: Could not be created.\n");
        return -1;
    }

    // Create hooks
    I->hooks = list_create();

    // Add hooked
    list_add(I->hooks, (void *)&hook_keepalive);
    list_add(I->hooks, (void *)&hook_lua);
    //list_add(I->hooks, (void *)&hook_translate);

    // Print a list of hooks registered
    list_execute(I->hooks, hooks_print);

    // First off the create - Lua module uses this to create the Lua state and load the config
    insim_hook_fire_create(I);

    do
    {
        int ccounter = 0;
        int coutput = -1;

        do
        {
            if (!I->internals.fast_connect)
                LSLEEP(I->socket.select_timeout.tv_sec);

            coutput = insim_connect(I);
            if (coutput == 0)
                break;
            ++ccounter;
        } while ((ccounter < I->internals.connection_attempts) && (!I->internals.reconnect));

        if (coutput < 0)
        {
            fprintf(stderr, "insim_connect: could not connect after %d attempts.\n", I->internals.connection_attempts);
            continue;
        }

        printf("Connection established\n");
        insim_hook_fire_connected(I);

        while ((!I->internals.quit) && (insim_recv(I) >= 0))
            ;

        insim_disconnect(I);

        if (!I->internals.quit)
            printf("Connection lost\n");
        else
            printf("Disconnected\n");

        insim_hook_fire_disconnected(I);

    } while ((!I->internals.quit) && (I->internals.reconnect));


    insim_hook_fire_close(I);
    list_destroy(I->hooks);

    insim_destroy(I);

//repeat
    fprintf(stdout,"\npress \"ESC\" to close the window");
    int ch;
    do {
        ch = _getch();
    } while (ch != 27);
//

	return 0;
}
